using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
namespace DAL
{
    public class Comments : DAL.DataManager<Comment>
    {
        private static Comments Instance = new Comments();
        static Comments() { }

        public override string TableName
        {
            get { return @"fstdt_comments"; }
        }

        public static string GetTableName()
        {
            return Instance.TableName;
        }

        protected override void CopyToItem(DataRow Row, Comment Item)
        {
            Item.DatePosted = Convert.ToDateTime(Row["DatePosted"]);

            Item.Visible = Convert.ToBoolean(Row["Visible"]);

            Item.Quote = Quotes.Item(Convert.ToInt64(Row["QuoteID"]));


            if (Row["Author"] != System.DBNull.Value)
            {
                Item.Author = Convert.ToString(Row["Author"]);
            }
            else
            {
                Item.Author = null;
            }


            Item.Post = Convert.ToString(Row["Comment"]);

            Item.IPAddress = Convert.ToString(Row["IPAddress"]);

            Item.IPRelationship = IPRelationships.Item(Convert.ToInt64(Row["IPRelationshipID"]));
        }

        protected override void CopyFromItem(DataManagerQuery query, Comment Item)
        {
            query.AddParam("DatePosted", Item.DatePosted);

            query.AddParam("Visible", Item.Visible);

            query.AddParam("QuoteID", Item.Quote.ID);

            if (Item.Author != null)
            {
                query.AddParam("Author", Item.Author);
            }
            else
            {
                query.AddParam("Author", System.DBNull.Value);
            }

            query.AddParam("Comment", Item.Post);

            query.AddParam("IPAddress", Item.IPAddress);

            if (Item.IPRelationship != null)
            {
                query.AddParam("IPRelationshipID", Item.IPRelationship.ID);
            }
            else
            {
                query.AddParam("IPRelationshipID", 0);
            }
        }

        public static Comment Item(Int64 id)
        {
            return Instance.GetItem(id);
        }

        public static List<Comment> All()
        {
            return Instance.GetItems();
        }

        public static void Add(Comment Item)
        {
            IPRelationship relationship = Managers.CommentManager.CurrentIPRelationship;
            Item.DatePosted = DateTime.Now;
            if (relationship.Banned)
            {
                Item.Visible = false;
            }
            else
            {
                Item.Visible = true;
            }
            Item.IPRelationship = relationship;
            Instance.Insert(Item);

            if (relationship.Banned == false)
            {
                Item.Quote.LatestComment = Item;
                Item.Quote.TotalComments += 1;
                Quotes.Save(Item.Quote);
            }
        }

        public static void Save(Comment Item)
        {
            Instance.Update(Item);
        }

        private static void AddVisibleParam(DataManagerQuery query)
        {
            if (Managers.CommentManager.CurrentIPRelationship.Banned == false)
            {
                query.AddParam("Visible", true);
            }
        }

        public static List<Comment> GetByQuote(Quote quote)
        {
            DataManagerQuery query = new DataManagerQuery();
            AddVisibleParam(query);
            query.AddParam("QuoteID", quote.ID);
            query.AddSort("ID", Sort.Desc);
            return Instance.GetItems(query);
        }

        public static DataManagerPage<Comment> GetByQuoteAndPage(Quote quote, int page)
        {
            DataManagerQuery query = new DataManagerQuery();
            AddVisibleParam(query);
            query.AddParam("QuoteID", quote.ID);
            query.AddSort("ID", Sort.Asc);
            return Instance.GetItemsByPage(query, page, 25);
        }

        public static DataManagerPage<Comment> GetLatestCommentByQuote(Quote quote)
        {
            DataManagerQuery query = new DataManagerQuery();
            AddVisibleParam(query);
            query.AddParam("QuoteID", quote.ID);
            query.AddSort("ID", Sort.Desc);
            return Instance.GetItemsByPage(query, 1, 25);
        }

        public static DataManagerPage<Comment> GetByIPRelationshipAndPage(IPRelationship relationship, int page)
        {
            DataManagerQuery query = new DataManagerQuery();
            query.AddParam("IPRelationshipID", relationship.ID);
            query.AddSort("ID", Sort.Desc);
            return Instance.GetItemsByPage(query, page, 25);
        }

        public static List<Comment> GetByIPRelationship(IPRelationship relationship)
        {
            DataManagerQuery query = new DataManagerQuery();
            query.AddParam("IPRelationshipID", relationship.ID);
            return Instance.GetItems(query);
        }

        public static List<Comment> GetByIPRelationshipAndVisible(IPRelationship relationship, bool visible)
        {
            DataManagerQuery query = new DataManagerQuery();
            query.AddParam("IPRelationshipID", relationship.ID);
            query.AddParam("Visible", visible);
            return Instance.GetItems(query);
        }

        public static void UpdateByIPRelationship(IPRelationship relationship)
        {
            bool visible;

            // I prefer to spell out my If statement rather than saying visible = relationship.Banned,
            // because its just more self-explanatory
            if (relationship.Banned == true)
            {
                visible = true;
            }
            else
            {
                visible = false;
            }

            // if relationship.Banned is true, then this selects all posts that are currently
            // still visible, and sets them to invisible. Otherwise, it will select 
            // invisible posts and set them to visible.
            foreach (Comment comment in Comments.GetByIPRelationshipAndVisible(relationship, visible))
            {
                comment.Visible = !comment.Visible; // flipping the visibility
                Save(comment);
            }
        }

        public static DataManagerPage<Comment> Search(string author, string comment, int page)
        {
            author = Helpers.FullTextHelper.GetFullTextSearchParam(author);
            comment = Helpers.FullTextHelper.GetFullTextSearchParam(comment);

            DataManagerQuery query = new DataManagerQuery();
            if (!string.IsNullOrEmpty(author))
            {
                query.AddParam("author", Comparison.Contains, author);
            }

            if (!string.IsNullOrEmpty(comment))
            {
                query.AddParam("comment", Comparison.Contains, comment);
            }

            query.AddParam("Visible", 1);

            query.AddSort("ID", Sort.Desc);

            return Instance.GetItemsByPage(query, page, 25);
        }
    }

    public class Comment : DAL.DataManagerRow
    {
        private DateTime _DatePosted;
        public DateTime DatePosted
        {
            get
            {
                return _DatePosted;
            }
            set
            {
                _DatePosted = value;
            }
        }


        private bool _Visible;
        public bool Visible
        {
            get
            {
                return _Visible;
            }
            set
            {
                _Visible = value;
            }
        }


        private Quote _Quote;
        public Quote Quote
        {
            get
            {
                return _Quote;
            }
            set
            {
                _Quote = value;
            }
        }


        private string _Author;
        public string Author
        {
            get
            {
                return _Author;
            }
            set
            {
                _Author = value;
            }
        }


        private string _Post;
        public string Post
        {
            get
            {
                return _Post;
            }
            set
            {
                _Post = value;
            }
        }


        private string _IPAddress;
        public string IPAddress
        {
            get
            {
                return _IPAddress;
            }
            set
            {
                _IPAddress = value;
            }
        }

        private IPRelationship _IPRelationship;
        public IPRelationship IPRelationship
        {
            get
            {
                return _IPRelationship;
            }
            set
            {
                _IPRelationship = value;
            }
        }
    }
}
